package com.lxx.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.lxx.utils.DataSourceDirectorUtil;

/**
 * @author HP
 * 一层一层注入,先创建DataSource，在创建SqlSessionFactory在创建事务，最后包装到SqlSessionTemplate中。
 * 其中需要制定分库的mapper文件地址，以及分库到层代码
 */
@Configuration
//这块的注解就是指明了扫描dao层，并且给dao层注入指定的SqlSessionTemplate。所有@Bean都需要按照命名指定正确。
@MapperScan(basePackages = "com.lxx.dao")
public class DataSourceConfig {
 
	//mapper.xml的路径
	@Value("${mybatis.mapper-locations}")
	private String mybatis_mapper_locations;
	//实体类别名的包名路径
	@Value("${mybatis.type-aliases-package}")
	private String mybatis_type_aliases_package;
	
	@Bean(name = "masterDataSource")
	@Primary
    @ConfigurationProperties(prefix = "spring.datasource.test2")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }
 
	@Bean(name = "slaveDataSource")
	@ConfigurationProperties(prefix = "spring.datasource.test1")
	public DataSource slaveDataSource() {
		return DataSourceBuilder.create().build();
	}
    /*@Bean(name = "masterSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mybatis_mapper_locations));
        bean.setTypeAliasesPackage(mybatis_type_aliases_package);
        return bean.getObject();
    }
 
    @Bean(name = "masterTransactionManager")
    @Primary
    public DataSourceTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
 
    @Bean(name = "masterSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }*/
	//========================================slave数据源============================
 
	 /**
     * Dynamic data source.
     *
     * @return the data source
     */
    @Bean("dynamicDataSource")
    public DataSource dynamicDataSource() {
    	DynamicDataSource dynamicRoutingDataSource = new DynamicDataSource();
        Map<Object, Object> dataSourceMap = new HashMap<>(4);
        dataSourceMap.put(DataSourceDirectorUtil.MASTER, masterDataSource());
        dataSourceMap.put(DataSourceDirectorUtil.SLAVE, slaveDataSource());
        //dataSourceMap.put(DataSourceKey.slaveBeta.name(), slaveBeta());
        //dataSourceMap.put(DataSourceKey.slaveGamma.name(), slaveGamma());

        // 将 master 数据源作为默认指定的数据源
        dynamicRoutingDataSource.setDefaultTargetDataSource(masterDataSource());
        // 将 master 和 slave 数据源作为指定的数据源
        dynamicRoutingDataSource.setTargetDataSources(dataSourceMap);

        // 将数据源的 key 放到数据源上下文的 key 集合中，用于切换时判断数据源是否有效
        //DynamicDataSourceContextHolder.dataSourceKeys.addAll(dataSourceMap.keySet());

        // 将 Slave 数据源的 key 放在集合中，用于轮循
        //DynamicDataSourceContextHolder.slaveDataSourceKeys.addAll(dataSourceMap.keySet());
        //DynamicDataSourceContextHolder.slaveDataSourceKeys.remove(DataSourceKey.master.name());
        return dynamicRoutingDataSource;
    } 
    
    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 配置数据源，此处配置为关键配置，如果没有将 dynamicDataSource 作为数据源则不能实现切换
        sqlSessionFactoryBean.setDataSource(dynamicDataSource());
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mybatis_mapper_locations));
        sqlSessionFactoryBean.setTypeAliasesPackage(mybatis_type_aliases_package);
        return sqlSessionFactoryBean;
    }
 
    @Bean(name = "TransactionManager")
    @Primary
    public DataSourceTransactionManager slaveTransactionManager(@Qualifier("dynamicDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
 
    /*@Bean(name = "SqlSessionTemplate")
    @Primary
    public SqlSessionTemplate slaveSqlSessionTemplate(@Qualifier("SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }*/
 
}